package com.automapper.sqlbuilder.impl;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.automapper.bytecode.ByteCodeFactory;
import com.automapper.bytecode.SqlWriter;
import com.automapper.bytecode.javassist.JavassistInsertSqlWriterCreator;
import com.automapper.constants.ParameterConstants;
import com.automapper.exception.AutoMapperException;
import com.automapper.sqlbuilder.SqlBuilderTemplate;
import com.automapper.utils.FieldFacade;
import com.automapper.utils.ObjectFacade;
import com.automapper.utils.ParameterUtils;
import com.automapper.utils.PropertiesFacade;

/**
 * List<Object> 集合转换sql，List<Map>不支持转换（InsertMapSqlBuilder实现List<Map>转换sql）
 * @author K
 *
 */
public class InsertSqlBuilder extends SqlBuilderTemplate {	
	
	private static final Logger log = LoggerFactory.getLogger(InsertSqlBuilder.class);
	
	private static final String VALUE = " #{%s[%s].%s} ";
	
	@Override
	public String buildSql(Object parameterObject, PropertiesFacade propertiesFacade) throws Exception {   
		AutoMapperException.NullRuntimeException(parameterObject, "Sorry,I refuse to build sql for a null object!");
		String sqlPlaceholderAlias = StringUtils.defaultIfBlank(propertiesFacade.getKey(), ParameterConstants.PARAM);
		List<String> values = new ArrayList<>();
		Map<String, Object> parameterMap = (Map<String, Object>) parameterObject;
		//获取传入参数
		List<Object> list = ParameterUtils.getParameterList(parameterMap);
		
		String tableName = getTableName(parameterMap);
		ObjectFacade objectFacade = new ObjectFacade(list.get(0));
		List<String> columns = objectFacade.getColumnNames();
		this.filter(parameterMap, columns);
		
		SqlWriter sqlWriter  = ByteCodeFactory.createSqlWriter(objectFacade, getExcludeColumn(parameterMap).toString(), sqlPlaceholderAlias);
		log.debug("sqlWriter生成的类:{}", sqlWriter.toString());
		
		StringBuilder tableSql = new StringBuilder();  
		StringBuilder valueSql = new StringBuilder(); 
	    tableSql.append("insert into ").append(tableName).append("(").append(StringUtils.join(columns, ",")).append(")");  
	    valueSql.append(" values ");
	    
	    for (int i = 0; i  < list.size(); i++) {
	    	Object obj = list.get(i);
	    	objectFacade = new ObjectFacade(obj);
	    	valueSql.append("(");
	    	if (propertiesFacade.isNullToDefaultValue()) {
				values.addAll(sqlWriter.writer(objectFacade.getOriginalObject(), i));
	    	} else {
	    		values.addAll(this.getInserValue(objectFacade, columns, i, sqlPlaceholderAlias));
	    	}
		    valueSql.append(StringUtils.join(values, ","));  
		    valueSql.append("),");
		    values.clear();
	    }
	    valueSql.delete(valueSql.lastIndexOf(","), valueSql.lastIndexOf(",") + 1);  
	    return tableSql.append(valueSql).toString();
	} 
	
	/**
	 * 生成入库参数
	 * @param obj 入库对象
	 * @param columns 数据库字段名
	 * @param index
	 * @return
	 * @throws Exception 
	 */
	private List<String> getInserValue(ObjectFacade objectFacade, List<String> columns, int index, String sqlPlaceholderAlias ) throws Exception {
		List<String> list = new ArrayList<>();
		for (String column : columns) {
			FieldFacade fieldFacade = objectFacade.getFiledFacade(column);
			if (fieldFacade.isId()) {
				if (fieldFacade.isNumEqNullOrEqZero()) {
					list.add("null");
				} else {
					list.add(String.format(VALUE, sqlPlaceholderAlias, index, fieldFacade.getFieldName()));
				}
			} else {
				//生成sql参数，参数采用ognl表达式：list[0].xxx
	    		list.add(String.format(VALUE, sqlPlaceholderAlias, index, fieldFacade.getFieldName()));
			}
		}
	    return list;
	}
}
